﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Runtime.Remoting;
using MFTool;
using Newtonsoft.Json;
using MF_Base;
using System.Text.RegularExpressions;
using MF_Base.Model;
using AutoUI.Areas.ConfigUI.EasyUICtrl;
using UIBase;
using System.Reflection;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq.Expressions;
using System.Text;
using System.Data;
using System.Configuration;
using DocumentIndex;

namespace AutoUI.Areas.ConfigUI.Controllers
{
    /// <summary>
    /// 反射调用UnitofWork相关方法(EF的方法)
    /// </summary>
    [Export]
    public class FormController : BaseController
    {
        private Type _entityType;
        protected virtual Type EntityType
        {
            get
            {
                if (_entityType == null)
                {
                    FormConfig formDef = GetFormConfig();

                    string entityFullName = formDef.EntityFullName;
                    string projName = formDef.ModuleName;
                    _entityType = ReflectionHelper.GetTypeBy(projName, entityFullName);
                }

                return _entityType;
            }
        }
        public virtual ActionResult PageView()
        {
            string UICode = QueryString("UICode");
            if(!string.IsNullOrEmpty(UICode))
            {
                GeneralFormViewBagItem(UICode);
            }
            
            return View();
        }

        protected void GeneralFormViewBagItem(string uiCode)
        {
            var form = UnitOfWork.GetSingle<FormConfig>(a => a.UICode == uiCode);
            form.CheckNotNull("未找到表单UICode:" + uiCode);
            string formHtml = "", script = "";
            script += form.Script + "\n\r";
            FetchFormHtmlAndScript(form, ref formHtml, ref script);

            ViewBag.FormHtml = formHtml;
            ViewBag.Script = script;
            ViewBag.FormId = form.Id;
        }

        protected virtual void BeforeSave(bool isNew, Dictionary<string, object> dic)
        {

        }

        [ValidateInput(false)]
        public JsonResult Save()
        {
            string formData = QueryString("formData");
            formData.CheckNotNullOrEmpty("formData");

            var dic = formData.JsonToDictionary();
            //add
            if (string.IsNullOrEmpty(dic.GetValue("Id")))
            {
                return Add(dic);
            }
            //update
            else
            {
                return Update(dic);
            }
        }

        public JsonResult Add(Dictionary<string, object> dic)
        {
            var entity = Activator.CreateInstance(EntityType, new object[] { });
            List<Action> actionList = new List<Action>();

            #region 主表数据
            var mainTabKey = GuidHelper.CreateTimeOrderID();
            dic.SetValue("Id", mainTabKey);
            dic.SetValue("CreateUserID", GetCurrentUserID());
            dic.SetValue("CreateUserName", GetCurrentUserName());
            dic.SetValue("ModifyUserID", GetCurrentUserID());
            dic.SetValue("ModifyUserName", GetCurrentUserName());

            BeforeSave(true, dic);
            ConvertHelper.UpdateEntity(entity, dic, false);

            #region 附件控件生成全文检索的索引
            string fileStorePath = ConfigurationManager.AppSettings["FileStorePath"];

            FormConfig formDef = GetFormConfig();
            //根据表单定义控件类型来对应生成全文检索索引
            if (formDef != null)
            {
                var dicList = formDef.CtrlSetting.JsonToDictionaryList();
                foreach (var item in dic)
                {
                    var ctrlSetDic = dicList.FirstOrDefault(a => a.GetValue("FieldName") == item.Key);
                    if (ctrlSetDic != null)
                    {
                        string ctrlType = ctrlSetDic.GetValue("CtrlType");
                        if (ctrlType == ControlType.MultiFileBox.ToString())
                        {
                            string fileNames = item.Value.ToString();
                            if (string.IsNullOrEmpty(fileNames)) continue;

                            var fileNameArr = fileNames.Split(',');
                            foreach (var fileNameS in fileNameArr)
                            {
                                var fileNameSArr = fileNameS.Split(new[] { "__________" }, StringSplitOptions.None);
                                string fileId = fileNameArr[0];
                                string fileName = System.IO.Path.GetFileNameWithoutExtension(fileNameArr[1]);
                                string tmpPath = fileStorePath + fileNames;
                                string physicalPath = Server.MapPath("/" + tmpPath);
                                IndexOperation opera = IndexOperation.GetAddOpera(physicalPath);
                                opera.Id = fileId;
                                opera.Title = fileName;
                                opera.CreateTime = DateTime.Now;
                                SearchIndexManager.GetInstance().AddOpreation(opera);
                            }
                        }
                    }
                }
            }
            #endregion

            //更新非配置级字段(非开发级)对应的数据,因为类模型中未形成该类字段
            actionList.Add(() => { ExcuteUpdateSqlWithConfigField(dic, EntityType, mainTabKey); });

            var addMethod = typeof(EFBase.UnitOfWork).GetMethod("Add", BindingFlags.Instance | BindingFlags.Public);
            addMethod.CheckNotNull("UnitOfWork中的Add方法未找到或者不可访问");
            addMethod = addMethod.MakeGenericMethod(EntityType);
            var res = addMethod.Invoke(UnitOfWork, new object[] { entity });
            #endregion

            #region 子表数据
            var propertyInfos = EntityType.GetProperties().Where(a => a.PropertyType.Name == "List`1" && a.GetAccessors().Any(b => b.IsVirtual));
            foreach (var prop in propertyInfos)
            {
                var innerType = prop.PropertyType.GenericTypeArguments[0];
                //基类必须是Entity                       
                if (innerType.BaseType.Name != "Entity")
                {
                    throw new Exception("List内对应类型的基类必须是Entity");
                }

                var subListJson = dic.GetValue(prop.Name);
                var subDicList = subListJson.JsonToDictionaryList();

                var subAddMethod = typeof(EFBase.UnitOfWork).GetMethod("Add", BindingFlags.Instance | BindingFlags.Public);
                subAddMethod.CheckNotNull("UnitOfWork中的Add方法未找到或者不可访问");
                subAddMethod = subAddMethod.MakeGenericMethod(innerType);

                //获取子表的主外键字段名
                var v = (ForeignKeyAttribute[])prop.GetCustomAttributes(typeof(ForeignKeyAttribute), false);
                v.CheckNotNullOrEmpty("外键字段{0}未定义ForeignKeyAttribute".ReplaceArg(prop.Name));
                var foreignKeyName = v[0].Name;
                foreignKeyName.CheckNotNull("外键字段{0}的ForeignKeyAttribute的未传外键名参数".ReplaceArg(prop.Name));

                foreach (var subDic in subDicList)
                {
                    var subEntity = Activator.CreateInstance(innerType, new object[] { });

                    //子表主键赋值
                    subDic.SetValue("Id", GuidHelper.CreateTimeOrderID());
                    //子表的主表外键字段赋值
                    subDic.SetValue(foreignKeyName, mainTabKey);

                    subDic.SetValue("CreateUserID", GetCurrentUserID());
                    subDic.SetValue("CreateUserName", GetCurrentUserName());
                    subDic.SetValue("ModifyUserID", GetCurrentUserID());
                    subDic.SetValue("ModifyUserName", GetCurrentUserName());

                    ConvertHelper.UpdateEntity(subEntity, subDic, false);

                    subAddMethod.Invoke(UnitOfWork, new object[] { subEntity });

                    //更新非配置级字段(非开发级)对应的数据,因为类模型中未形成该类字段
                    actionList.Add(() => { ExcuteUpdateSqlWithConfigField(subDic, innerType, subDic.GetValue("Id")); });
                }
            }
            #endregion

            Action action = () =>
            {
                UnitOfWork.Commit();
                foreach (var act in actionList)
                {
                    act.Invoke();
                }
            };
            this.ExecuteAction(action);
            return Json(res);
        }

        public JsonResult Delete(string ids)
        {
            ids.CheckNotNullOrEmpty("guid");
            var idArr = ids.JsonToObject<IEnumerable<string>>();
            BeforeDelete(idArr);//

            var delMethod = typeof(EFBase.UnitOfWork).GetMethod("DeleteByKey", BindingFlags.Instance | BindingFlags.Public);
            delMethod.CheckNotNull("UnitOfWork中的DeleteByKey方法未找到或者不可访问");
            delMethod = delMethod.MakeGenericMethod(EntityType);

            foreach (var id in idArr)
            {
                delMethod.Invoke(UnitOfWork, new object[] { id });
            }
            return Json(UnitOfWork.Commit());
        }

        protected virtual void BeforeDelete(IEnumerable<string> ids)
        {

        }

        public JsonResult Update(Dictionary<string, object> dic)
        {
            List<Action> actionList = new List<Action>();

            BeforeSave(false, dic);
            var mainTabKey = dic.GetValue("Id");
            #region 主表数据
            dic.SetValue("ModifyUserID", GetCurrentUserID());
            dic.SetValue("ModifyUserName", GetCurrentUserName());

            //取
            var getMethod = typeof(EFBase.UnitOfWork).GetMethod("GetByKey", BindingFlags.Instance | BindingFlags.Public);
            getMethod.CheckNotNull("UnitOfWork中的GetByKey方法未找到或者不可访问");
            getMethod = getMethod.MakeGenericMethod(EntityType);
            var entity = getMethod.Invoke(UnitOfWork, new object[] { mainTabKey });

            //更新
            ConvertHelper.UpdateEntity(entity, dic, false);

            #region 对付附件控件生成全文检索的索引
            string fileStorePath = ConfigurationManager.AppSettings["FileStorePath"];

            FormConfig formDef = GetFormConfig();
            if (formDef != null)
            {
                var dicList = formDef.CtrlSetting.JsonToDictionaryList();
                foreach (var item in dic)
                {
                    var ctrlSetDic = dicList.FirstOrDefault(a => a.GetValue("FieldName") == item.Key);
                    if (ctrlSetDic != null)
                    {
                        string ctrlType = ctrlSetDic.GetValue("CtrlType");
                        if (ctrlType == ControlType.MultiFileBox.ToString())
                        {
                            string fileNames = item.Value.ToString();
                            if (string.IsNullOrEmpty(fileNames)) continue;

                            var fileNameArr = fileNames.Split(',');
                            foreach (var fileNameS in fileNameArr)
                            {
                                var fileNameSArr = fileNameS.Split(new[] { "__________" }, StringSplitOptions.None);
                                string fileId = fileNameSArr[0];
                                string fileName = System.IO.Path.GetFileNameWithoutExtension(fileNameSArr[1]);
                                string tmpPath = fileStorePath + fileNames;
                                string physicalPath = Server.MapPath("/" + tmpPath);
                                IndexOperation opera = IndexOperation.GetAddOpera(physicalPath);
                                opera.Id = fileId;
                                opera.Title = fileName;
                                opera.CreateTime = DateTime.Now;
                                SearchIndexManager.GetInstance().AddOpreation(opera);
                            }
                        }
                    }
                }
            }
            #endregion

            //更新非配置级字段(非开发级)对应的数据,因为类模型中未形成该类字段
            actionList.Add(() => { ExcuteUpdateSqlWithConfigField(dic, EntityType, mainTabKey); });
            #endregion

            #region 子表数据
            var propertyInfos = EntityType.GetProperties().Where(a => a.PropertyType.Name == "List`1" && a.GetAccessors().Any(b => b.IsVirtual));
            foreach (var prop in propertyInfos)
            {
                var innerType = prop.PropertyType.GenericTypeArguments[0];
                //基类必须是Entity                       
                if (innerType.BaseType.Name != "Entity")
                {
                    throw new Exception("List内对应类型的基类必须是Entity");
                }

                var subListJson = dic.GetValue(prop.Name);
                var subDicList = subListJson.JsonToDictionaryList();
                var existIdList = subDicList.Select(a => a.GetValue("Id"));

                var subQuery = prop.GetValue(entity, null);
                //拷贝至subDBList中(否则foreach中执行delete会报错)
                Type genericListType = typeof(List<>);
                Type concreteListType = genericListType.MakeGenericType(innerType);
                var subDBList = (System.Collections.IEnumerable)Activator.CreateInstance(concreteListType, new object[] { subQuery });

                //增
                var subAddMethod = typeof(EFBase.UnitOfWork).GetMethod("Add", BindingFlags.Instance | BindingFlags.Public);
                subAddMethod.CheckNotNull("UnitOfWork中的Add方法未找到或者不可访问");
                subAddMethod = subAddMethod.MakeGenericMethod(innerType);
                //取
                var subGetMethod = typeof(EFBase.UnitOfWork).GetMethod("GetByKey", BindingFlags.Instance | BindingFlags.Public);
                subGetMethod.CheckNotNull("UnitOfWork中的GetByKey方法未找到或者不可访问");
                subGetMethod = subGetMethod.MakeGenericMethod(innerType);

                //获取子表的主外键字段名
                var v = (ForeignKeyAttribute[])prop.GetCustomAttributes(typeof(ForeignKeyAttribute), false);
                v.CheckNotNullOrEmpty("外键字段{0}未定义ForeignKeyAttribute".ReplaceArg(prop.Name));
                var foreignKeyName = v[0].Name;
                foreignKeyName.CheckNotNull("外键字段{0}的ForeignKeyAttribute的未传外键名参数".ReplaceArg(prop.Name));

                foreach (var subDic in subDicList)
                {
                    subDic.SetValue("ModifyUserID", GetCurrentUserID());
                    subDic.SetValue("ModifyUserName", GetCurrentUserName());

                    var subEntity = subGetMethod.Invoke(UnitOfWork, new object[] { subDic.GetValue("Id") });

                    //更新
                    if (subEntity != null)
                    {
                        ConvertHelper.UpdateEntity(subEntity, subDic, true);
                    }
                    //新增
                    else
                    {
                        subEntity = Activator.CreateInstance(innerType, new object[] { });

                        //子表主键赋值
                        subDic.SetValue("Id", GuidHelper.CreateTimeOrderID());
                        //子表的主表外键字段赋值
                        subDic.SetValue(foreignKeyName, mainTabKey);

                        subDic.SetValue("CreateUserID", GetCurrentUserID());
                        subDic.SetValue("CreateUserName", GetCurrentUserName());

                        ConvertHelper.UpdateEntity(subEntity, subDic, false);
                        subAddMethod.Invoke(UnitOfWork, new object[] { subEntity });
                    }

                    //更新非配置级字段(非开发级)对应的数据,因为类模型中未形成该类字段
                    actionList.Add(() => { ExcuteUpdateSqlWithConfigField(subDic, innerType, subDic.GetValue("Id")); });
                }

                //删
                var subDeleteMethod = typeof(EFBase.UnitOfWork).GetMethod("DeleteByKey", BindingFlags.Instance | BindingFlags.Public);
                subDeleteMethod.CheckNotNull("UnitOfWork中的DeleteByKey方法未找到或者不可访问");
                subDeleteMethod = subDeleteMethod.MakeGenericMethod(innerType);

                foreach (var subItem in subDBList)
                {
                    string id = innerType.GetProperty("Id").GetValue(subItem).ToString();
                    if (!existIdList.Contains(id))
                    {
                        subDeleteMethod.Invoke(UnitOfWork, new object[] { id });
                    }
                }
            }
            #endregion

            Action action = () =>
            {
                UnitOfWork.Commit();
                foreach (var act in actionList)
                {
                    act.Invoke();
                }
            };
            this.ExecuteAction(action);
            return Json(entity);
        }

        protected virtual void AfterGetData(bool isNew, Dictionary<string, object> dic)
        {

        }

        /// <summary>
        /// 根据表单定义默认值设置获取默认值
        /// </summary>
        /// <param name="uiCode"></param>
        /// <returns></returns>
        public JsonResult GetDefaultValue(string uiCode)
        {
            Dictionary<string, object> dicRes = new Dictionary<string, object>();
            if (string.IsNullOrEmpty(uiCode))
                return Json(dicRes);

            FormConfig formConfig = UnitOfWork.GetSingle<FormConfig>(a => a.UICode == uiCode);
            formConfig.CheckNotNull("未找到UICode为{0}的表单定义".ReplaceArg(uiCode));
            var ctrlAttrList = formConfig.GetCtrlAttrList();

            //从数据库获取默认值
            var dbDefaultValueCtrlList = new List<Dictionary<string, object>>();
            var sourceNameList = new List<string>();

            foreach (var ctrlAttr in ctrlAttrList)
            {
                var defaultValue = ctrlAttr.GetValue("DefaultValue");
                if (string.IsNullOrEmpty(defaultValue)) continue;

                //需要用实际数据来替换

                if (defaultValue == DefaultValueSymbol.CurrentUserId.ToString())
                {
                    defaultValue = GetCurrentUserID();
                }
                else if (defaultValue == DefaultValueSymbol.CurrentUserName.ToString())
                {
                    defaultValue = GetCurrentUserName();
                }
                else if (defaultValue == DefaultValueSymbol.CurrentDate.ToString())
                {
                    defaultValue = DateTime.Now.ToString("yyyy-MM-dd");
                }
                else if (defaultValue == DefaultValueSymbol.CurrentTime.ToString())
                {
                    defaultValue = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
                }
                //数据源中获取
                else
                {
                    var sourceName = defaultValue.TrimStart('{').TrimEnd('}').Split('.')[0];//sourceName.FieldName
                    if (!string.IsNullOrEmpty(sourceName) && !sourceNameList.Contains(sourceName))
                    {
                        sourceNameList.Add(sourceName);
                    }

                    dbDefaultValueCtrlList.Add(ctrlAttr);
                    continue;
                }
                dicRes.SetValue(ctrlAttr.GetValue("FieldName"), defaultValue);
            }

            var sourceDicList = formConfig.DataSourceSetting.JsonToDictionaryList().
                Where(a => sourceNameList.Contains(a.GetValue("Name")));
            foreach (var sourceDic in sourceDicList)
            {
                var sqlHelper = SqlHelper.CreateSqlHelper(sourceDic.GetValue("DBName"));
                string sql = sourceDic.GetValue("SQL");

                //根据请求参数对sql语句进行更新
                Regex reg = new Regex("\\{[0-9a-zA-Z_\\.]*\\}");
                sql = reg.Replace(sql, (Match m) =>
                {
                    return QueryString(m.Value);
                });

                var dicList = sqlHelper.ExcuteTable(sql).ToDicList();

                //塞进sourceDic供后续调用
                sourceDic.SetValue("DBSourceDicList", dicList);
            }

            foreach (var dbDefaultValueCtrl in dbDefaultValueCtrlList)
            {
                var tmpDbDefaultValue = dbDefaultValueCtrl.GetValue("DefaultValue").TrimStart('{').TrimEnd('}');
                var dbDefaultValueArr = tmpDbDefaultValue.Split('.');
                if (dbDefaultValueArr.Length == 1)
                {
                    var sourceDic = sourceDicList.FirstOrDefault(a => a.GetValue("Name") == dbDefaultValueArr[0]);
                    var dbSourceDicList = sourceDic.GetObject("DBSourceDicList") as List<Dictionary<string, object>>;

                    //验证对应控件是否是子表,否则不赋值
                    if (dbDefaultValueCtrl.GetValue("CtrlType") == ControlType.SubDataGrid.ToString())
                        dicRes.SetValue(dbDefaultValueCtrl.GetValue("FieldName"), dbSourceDicList);
                }
                else
                {
                    var sourceName = dbDefaultValueArr[0];
                    var sqlColName = dbDefaultValueArr[1];
                    var sourceDic = sourceDicList.FirstOrDefault(a => a.GetValue("Name") == sourceName);
                    var dbSourceDicList = sourceDic.GetObject("DBSourceDicList") as List<Dictionary<string, object>>;
                    if (dbSourceDicList.Count() > 0)
                    {
                        dicRes.SetValue(dbDefaultValueCtrl.GetValue("FieldName"), dbSourceDicList[0].GetValue(sqlColName));
                    }
                }
            }

            AfterGetData(true, dicRes);
            return Json(dicRes);
        }

        public JsonResult Get(string Id)
        {
            Dictionary<string, object> dicRes = new Dictionary<string, object>();
            if (!string.IsNullOrEmpty(Id))
            {
                var getMethod = typeof(EFBase.UnitOfWork).GetMethod("GetByKey", BindingFlags.Instance | BindingFlags.Public);
                getMethod.CheckNotNull("UnitOfWork中的GetByKey方法未找到或者不可访问");
                getMethod = getMethod.MakeGenericMethod(EntityType);
                var res = getMethod.Invoke(UnitOfWork, new object[] { Id });

                res.CheckNotNull("未找到Id为{0}的数据".ReplaceArg(Id));
                dicRes = res.ToJsonIgnoreLoop().JsonToDictionary();
                var propertyInfos = EntityType.GetProperties();
                foreach (var prop in propertyInfos)
                {
                    //对应外键表
                    //一对一
                    if (prop.PropertyType.BaseType.Name == "Entity" && prop.GetAccessors().Any(a => a.IsVirtual))//virtual
                    {
                        object foreignObj = prop.GetValue(res, null);//virtual 懒加载 执行一次数据库查询
                        if (foreignObj != null)
                        {
                            var dic = foreignObj.ToJsonIgnoreLoop().JsonToDictionary();
                            var foreignTableName = GetForeignKeyNameByVirtualPropFieldName(prop.Name, propertyInfos);
                            foreignTableName.CheckNotNullOrEmpty("外键表字段{0}的对应外键字段必须设置ForeignKeyAttribute".ReplaceArg(prop.Name));
                            foreach (var tmp in dic)
                            {
                                dicRes.SetValue(foreignTableName + "__________" + tmp.Key, tmp.Value);//xxx__________xxxx 相当于xxx对象的xxxx属性
                            }
                        }
                    }
                    //对应子表
                    else if (prop.PropertyType.Name == "List`1" && prop.GetAccessors().Any(b => b.IsVirtual))
                    {
                        var subListJson = dicRes.GetValue(prop.Name);
                        var subDicList = subListJson.JsonToDictionaryList();
                        var innerType = prop.PropertyType.GenericTypeArguments[0];
                        foreach (var subDic in subDicList)
                        {
                            FillDicWithConfigField(subDic, innerType, subDic.GetValue("Id"));
                        }
                        dicRes.SetValue(prop.Name, subDicList);
                    }
                }

                FillDicWithConfigField(dicRes, EntityType, Id);
                AfterGetData(false, dicRes);
            }

            return Json(dicRes);
        }

        private void FetchFormHtmlAndScript(FormConfig form, ref string res, ref string script)
        {
            res = "";
            string formLayout = Server.HtmlDecode(form.LayOutSetting);
            var ctrlAttrList = form.GetCtrlAttrList();
            //hiddenCtrl不在formlayout布局内
            foreach (var ctrlAttr in
                ctrlAttrList.Where(a => a.GetValue("CtrlType") == ControlType.HiddenInput.ToString()))
            {
                var hiddenCtrl = EasyUICtrlFactory.GetCtrl(ControlType.HiddenInput.ToString(), ctrlAttr.GetValue("FieldName"));
                hiddenCtrl.Prepare();
                res += hiddenCtrl.GetCtrlHtm();
            }

            foreach (var ctrlAttr in
                ctrlAttrList.Where(a => a.GetValue("CtrlType") != ControlType.HiddenInput.ToString()))
            {
                //控件html
                var ctrl = GeneralEasyuiCtrl(ctrlAttr);
                if (ctrl == null) continue;

                script += ctrl.GetScript() + "\n\r";
                string easyuiCtrlHtml = ctrl.GetCtrlHtm();
                if (string.IsNullOrEmpty(easyuiCtrlHtml))
                    continue;

                //替换标签
                string fieldToReplace = ctrlAttr.GetValue("ColumnName");
                if (string.IsNullOrEmpty(fieldToReplace))
                {
                    fieldToReplace = ctrlAttr.GetValue("FieldName");
                }
                if (!string.IsNullOrEmpty(formLayout))
                    formLayout = formLayout.Replace("{" + fieldToReplace + "}", easyuiCtrlHtml);
            }
            res += formLayout;
        }

        private FormConfig GetFormConfig()
        {
            string uiCode = QueryString("UICode");
            string formId = QueryString("formId");
            FormConfig formDef = null;
            if (!string.IsNullOrEmpty(formId))
            {
                formDef = UnitOfWork.GetByKey<FormConfig>(formId);
                formDef.CheckNotNull("未找到表单Id:" + formId);
            }
            else if (!string.IsNullOrEmpty(uiCode))
            {
                formDef = UnitOfWork.GetSingle<FormConfig>(a => a.UICode == uiCode);
                formDef.CheckNotNull("未找到表单UICode:" + uiCode);
            }
            return formDef;
        }

        private CtrlBase GeneralEasyuiCtrl(Dictionary<string, object> ctrl)
        {
            string strCtrlType = ctrl.GetValue("CtrlType");
            if (string.IsNullOrEmpty(strCtrlType))
                return null;

            string dataOptions = ctrl.GetValue("Detail");
            var dOptionDic = dataOptions.JsonToDictionary();
            var fieldName = ctrl.GetValue("FieldName");

            if (!string.IsNullOrEmpty(dataOptions))
            {
                #region  class
                if (string.IsNullOrEmpty(ctrl.GetValue("IsVisible")) || ctrl.GetValue("IsVisible") != "是")
                {
                    dOptionDic.Add("visible", "false");
                }
                #endregion
                if (string.IsNullOrEmpty(ctrl.GetValue("Enable")) || ctrl.GetValue("Enable") != "是")
                {
                    dOptionDic.SetValue("disabled", true);
                }
            }
            EasyUICtrlPrepareData prepareData = new EasyUICtrlPrepareData()
            {
                DataOptions = dOptionDic
            };

            var easyUICtrl = EasyUICtrlFactory.GetCtrl(strCtrlType, fieldName, prepareData);
            easyUICtrl.Prepare();
            return easyUICtrl;
        }

        /// <summary>
        /// 根据非配置级字段(非开发级)来形成sql语句
        /// </summary>
        /// <param name="entityDic"></param>
        /// <returns></returns>
        private void ExcuteUpdateSqlWithConfigField(Dictionary<string, object> entityDic, Type entityType, string ID)
        {
            string moduleName = entityType.FullName.Split('.')[0];
            var sqlHelper = new SqlHelper(moduleName);

            string tableName = entityType.Name;
            var entityTable = sqlHelper.ExcuteTable("select top 1 * from {0}".ReplaceArg(tableName));
            entityTable.Clear();

            StringBuilder sb = new StringBuilder();
            foreach (DataColumn col in entityTable.Columns)
            {
                string name = col.ColumnName;
                //非配置级字段略过
                if (entityType.GetProperty(name) != null)
                    continue;

                var valObj = entityDic.GetValue(name);
                if (valObj == null)
                    continue;
                string value = valObj.ToString();
                if (String.IsNullOrEmpty(value))
                    sb.AppendFormat(",{0}=NULL", name);
                else
                    sb.AppendFormat(",{0}='{1}'", name, value.Replace("'", "''"));
            }

            if (sb.Length != 0)
            {
                string sql = string.Format(@"UPDATE {0} SET {2} WHERE ID='{1}'", tableName, ID, sb.ToString().Trim(','));
                sqlHelper.ExcuteNoQuery(sql);
            }
        }

        private void FillDicWithConfigField(Dictionary<string, object> entityDic, Type entityType, string ID)
        {
            string moduleName = entityType.FullName.Split('.')[0];
            var sqlHelper = new SqlHelper(moduleName);

            string tableName = entityType.Name;
            var entityTable = sqlHelper.ExcuteTable("select * from {0} where Id = '{1}'".ReplaceArg(tableName, ID));
            if (entityTable.Rows.Count > 0)
            {
                DataRow dr = entityTable.Rows[0];
                foreach (DataColumn col in entityTable.Columns)
                {
                    string name = col.ColumnName;
                    //非配置级字段略过
                    if (entityType.GetProperty(name) != null)
                        continue;

                    entityDic.SetValue(name, dr[name]);
                }
            }
        }

        /// <summary>
        /// 根据virtual对应的外键表变量名获取外键变量名
        /// </summary>
        /// <param name="virtualPropFieldName"></param>
        /// <param name="props"></param>
        /// <returns></returns>
        private string GetForeignKeyNameByVirtualPropFieldName(string virtualPropFieldName, PropertyInfo[] props)
        {
            foreach (var prop in props)
            {
                var v = (ForeignKeyAttribute[])prop.GetCustomAttributes(typeof(ForeignKeyAttribute), false);
                if (v != null && v.Length > 0 && v[0].Name == virtualPropFieldName)
                {
                    return prop.Name;
                }
            }
            return "";
        }
    }
}
